import hilog from '@ohos.hilog';
import { Context } from '@kit.AbilityKit';
import { FileIOUtil } from '../FileIoUtil';


let format: string = `%{public}s`;

export enum MessageLevel {
  Debug = 11,
  Error = 10,
  Info = 8,
  Log = 7,
  Warn = 9
}

export interface IConsoleMessage {
  message: string
  source: string
  lineNumber: number
  messageLevel: MessageLevel
}


/**
 * @des 日志系统
 * TODO 去除写入文件功能
 * @author ZhangYiChi
 * @date 2024/7/10 16:08
 */
export class LogUtil {
  static appTag = "app"
  private static mTag: string = "HarmonyOSLog"
  private static mDomain: number = 0x0000
  private static mClose: boolean = false
  private static mHilog: boolean = false //默认是用hilog进行打印
  private static mShowLogLocation: boolean = true //展示点击的位置
  private static mLogSize = 800 //打印的最大长度，默认是800
  private static fileIoUtil: FileIOUtil

  static init(context: Context) {
    if (!!!LogUtil.fileIoUtil) {
      LogUtil.fileIoUtil = new FileIOUtil(context.filesDir)
      LogUtil.fileIoUtil.clean()
    }
  }

  public static webConsole(tag: string = "webConsole", event: IConsoleMessage) {
    if (event.messageLevel === MessageLevel.Error) {
      LogUtil.e(tag, event.message)
    } else if (event.messageLevel === MessageLevel.Info) {
      LogUtil.i(tag, event.message)
    } else if (event.messageLevel === MessageLevel.Warn) {
      LogUtil.w(tag, event.message)
    } else if (event.messageLevel === MessageLevel.Log || event.messageLevel === MessageLevel.Debug) {
      LogUtil.d(tag, event.message)
    }
  }

  public static i(tag: string, ...msg: any[]) {
    LogUtil.logLevel(hilog.LogLevel.INFO, tag, msg)
  }

  public static d(tag: string, ...msg: any[]) {
    LogUtil.logLevel(hilog.LogLevel.DEBUG, tag, msg)
  }

  public static e(tag: string, ...msg: any[]) {
    LogUtil.logLevel(hilog.LogLevel.ERROR, tag, msg)
  }

  public static w(tag: string, ...msg: any[]) {
    LogUtil.logLevel(hilog.LogLevel.WARN, tag, msg)
  }

  public static async zip() {
    return await LogUtil.fileIoUtil.zip()
  }


  /**
   * 获取输出位置
   * */
  static getMessage(level: hilog.LogLevel, tag: string, ...message: any[]): string {
    var log = tag + " ┌───────────────────────────────────────────────────────────────────────────────────────"
    log = log.substring(0, log.length - tag.length) + "\n"

    try {
      if (this.mShowLogLocation && level == hilog.LogLevel.ERROR) {
        //展示位置
        const stackTrace = new Error().stack
        const traceArray = stackTrace.split('\n')
        const trace = traceArray[traceArray.length-2]
        log = log + "|" + trace
      }
      message.forEach((msg) => {
        var type = typeof msg
        if (type == "object") {
          //是对象
          msg = this.getObjectToJson(msg, tag)
        } else if (type == "string") {
          //判断是否包含大括号
          let content = msg + ""

          if (content.startsWith("{") && content.endsWith("}")) {
            //对象
            const obj = JSON.parse(msg)
            msg = this.getObjectToJson(obj, tag)
          } else {
            msg = content
          }
        }
        log = log + "\n" + tag + " |    " + msg
      })


    } catch (e) {
      log = log + "\n" + tag + " |    " + "error:" + JSON.stringify(e)
    }
    log = log + "\n" + tag + " └───────────────────────────────────────────────────────────────────────────────────────"
    return log
  }

  private static innerLog(tag: string, str: string) {
    let count = 500
    if (str.length < count) {
      console.log("test", tag, str)
    } else {
      str = str.replace(/\\/g, '')
      let end = count;
      console.log("test", "start ====>")
      for (let index = 0, len = str.length; index < len; ) {
        end = index + count;
        if (end > len) {
          end = len
        }
        console.log("test", tag, str.substring(index, end))
        index = end

      }
      console.log("test", "end <====")
    }
  }

  /*
   *统一输出日志
   * */
  private static logLevel(level: hilog.LogLevel, tag: string, ...message: any[]) {
    //如果关闭状态，则不打印日志
    if (this.mClose) {
      return
    }

    //未传递时
    if (tag == undefined) {
      tag = this.mTag
    }

    const content = this.getMessage(level, tag, message) //最终的内容展示
    if (level > hilog.LogLevel.DEBUG) {
      LogUtil.fileIoUtil?.write(content)
    }

    const len = content.length / this.mLogSize
    for (var i = 0; i < len; i++) {
      var con = content.substring(i * this.mLogSize, (i + 1) * this.mLogSize)
      if (i != 0) {
        con = tag + " |    " + con
      }
      //打印日志
      if (this.mHilog) {
        //使用hilog
        switch (level) {
          case hilog.LogLevel.INFO: //info
            hilog.info(this.mDomain, tag, con)
            break
          case hilog.LogLevel.WARN: //WARN
            hilog.warn(this.mDomain, tag, con)
            break
          case hilog.LogLevel.DEBUG: //DEBUG
            hilog.debug(this.mDomain, tag, con)
            break
          case hilog.LogLevel.ERROR: //ERROR
            hilog.error(this.mDomain, tag, con)
            break
          case hilog.LogLevel.FATAL: //FATAL
            hilog.fatal(this.mDomain, tag, con)
            break
        }
      } else {
        //使用console
        switch (level) {
          case hilog.LogLevel.INFO: //info
            console.info(con)
            break
          case hilog.LogLevel.WARN: //WARN
            console.warn(con)
            break
          case hilog.LogLevel.DEBUG: //DEBUG
            console.debug(con)
            break
          case hilog.LogLevel.ERROR: //ERROR
            console.error(con)
            break
          case hilog.LogLevel.FATAL: //FATAL
            console.log(con)
            break
        }
      }

    }

  }

  /*
   *对象转Json
   * */
  private static getObjectToJson(message: object, tag: string = ""): String {
    try {
      const json = JSON.stringify(message, null, 2)
      const endMessage = json.replace(/\n/g, "\n" + tag + " |    ")
      return endMessage
    } catch (e) {
    }
    return ""
  }
}